<?php defined('SYSPATH') or die('No direct script access.');

/**
 * Moo Service Driver Library
 * http://www.moo.com/api/
 *
 * $Id$
 *
 * @package		Service Module
 * @author		Alex Sancho
 * @copyright	(c) 2008 Alex Sancho
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *	  notice, this list of conditions and the following disclaimer in the
 *	  documentation and/or other materials provided with the distribution.
 * 3. Neither the name of copyright holders nor the names of its
 *	  contributors may be used to endorse or promote products derived
 *	  from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.	IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

class Service_Moo_Driver extends Service_Driver
{
	protected $api_url = "www.moo.com/api/api.php";
	protected $type = 'minicard';
	protected $chooser = true;
	protected $designs = array();
	protected $options = array
	(
		'version' 	=> '0.7',
		'api_key'	=> '',
		'call' 		=> 'build',
		'return_to'	=> '',
		'fail_to'	=> ''
	);

	/**
	 *	__construct
	 * 
	 * @param array $config
	 * @return void
	 * @access public
	 * 
	 */
	public function __construct($config = array())
	{
		$config += Kohana::config('service.moo');
		
		foreach($config as $key => $val) 
		{
			$method = 'set_'.$key;

			if (method_exists($this, $method))
				$this->$method($val);
		}
	}
	
	/**
	 * set_apikey
	 * 
	 * @param string $key
	 * @return object
	 * @access public
	 * 
	 */
	public function set_api_key($key)
	{
		$this->options['api_key'] = $key;
		return $this;
	}
	
	/**
	 * set_api_version
	 * 
	 * @param float $version
	 * @return object
	 * @access public
	 * 
	 */
	public function set_api_version($version)
	{
		$this->options['version'] = $version;
		return $this;
	}
	
	/**
	 * set_type
	 *
	 * @param string $type
	 * @return object
	 * @access public
	 * 
	 */
	public function set_type($type) 
	{
		$this->type = $type;
		return $this;
	}
	
	/**
	 * set_chooser
	 *
	 * @param boolean $chooser
	 * @return object
	 * @access public
	 * 
	 */
	public function set_chooser($chooser) 
	{
		$this->chooser = (bool) $chooser;
		return $this;
	}
	
	/**
	 * set_return
	 *
	 * @param string $url
	 * @return object
	 * @access public
	 * 
	 */
	public function set_return($url) 
	{
		$this->options['return_to'] = $url;
		return $this;
	}
	
	/**
	 * set_fail
	 *
	 * @param string $url
	 * @return object
	 * @access public
	 * 
	 */
	public function set_fail($url) 
	{
		$this->options['fail_to'] = $url;
		return $this;
	}

	/**
	 * add_design
	 *
	 * @param string $url
	 * @param string $type
	 * @param mixed $crop
	 * @param mixed $text
	 * @return void
	 * @access public
	 * 
	 */
	public function add_design($url = null, $type = 'variable', $crop = 'auto', $text = null) 
	{
		if (valid::url($url)) 
		{
			$this->designs[] = $index = moo::add_image($url, $type, $crop);

			if ( ! empty($text))
				moo::add_text($index, $text);

			return $this;
		} 
		elseif (is_array($url))
		{
			$this->designs[] = $index = moo::add_image(array_merge(array('type' => $type, 'crop' => $crop), $url));

			if ( ! empty($text))
				moo::add_text($index, $text);

			return $this;
		}
		else 
		{
			throw new Kohana_User_Exception('Moo Driver', Kohana::lang('service.invalid_moo_design'));
		}
	}
	
	/**
	 * add_text
	 * 
	 * @param integer $index
	 * @param mixed $data
	 * @param string $line
	 * @return object
	 * @access public
	 * 
	 */
	public function add_text($index, $data, $line = null)
	{
		moo::add_text($index, $data, $line);
		return $this;
	}

	/**
	 * get_images
	 * Returns the array of images
	 *
	 * @param bool $url_only
	 * @return array
	 * @access public
	 * 
	 */
	public function get_images($url_only = true) 
	{
		return moo::get_images($url_only);
	}
	
	/**
	 * remove_image
	 *
	 * @param integer $index
	 * @param string $type
	 * @return mixed
	 * @access public
	 * 
	 */
	public function remove_image($index = null, $type = 'variable') 
	{
		return moo::remove_image($index, $type);
	}
	
	/**
	 * get_xml
	 * 
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function get_xml()
	{
		return $this->post(array('xml' => $this->to_xml(), 'method' => 'direct'))->api_call();
	}
	
	/**
	 * redirect
	 *
	 * @return void
	 * @access public
	 * 
	 */
	public function redirect() 
	{
		$xml = $this->get_xml();
		
		header('location: '.str_replace('&amp;', '&', $xml->payload->start_url));
	}
	
	/**
	 * to_xml
	 *
	 * @return string
	 * @access protected
	 * 
	 */
	protected function to_xml() 
	{
		$xml = new DOMDocument("1.0", "UTF-8");
		$moo = $xml->createElement('moo');
		$moo->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
		$moo->setAttribute('xsi:noNamespaceSchemaLocation', 'http://www.moo.com/xsd/api_0.7.xsd');
		
		$request = $xml->createElement('request');

		foreach($this->options as $key => $val)
			if ( ! empty($val))
				$request->appendChild($xml->createElement($key, $val));
		
		$payload = $xml->createElement('payload');

		if ($this->chooser === true)
		{
			$chooser = $xml->createElement('chooser');
			$chooser->appendChild($xml->createElement('product_type', $this->type));

			$images = $xml->createElement('images');
			$chooser->appendChild($images);

			$f = $xml->createDocumentFragment();
			foreach($this->designs as $d)
				$f->appendXML(moo::to_xml($d, true));
			
			$images->parentNode->replaceChild($f, $images);
			$payload->appendChild($chooser);
		}
		else
		{
			$products = $xml->createElement('products');
			$product = $xml->createElement('product');
			$designs = $xml->createElement('designs');
			$design = $xml->createElement('design');
			$designs->appendChild($design);
			$product->appendChild($xml->createElement('product_type', $this->type));
			$product->appendChild($designs);

			$f = $xml->createDocumentFragment();
			foreach($this->designs as $d)
				$f->appendXML(moo::to_xml($d));

			$design->parentNode->replaceChild($f, $design);

			$products->appendChild($product);
			$payload->appendChild($products);
		}

		$moo->appendChild($request);
		$moo->appendChild($payload);
		$xml->appendChild($moo);

		return $xml->saveXML();
	}
	
	/**
	 * api_call
	 * 
	 * @return object SimpleXMLElement Object
	 * @access protected
	 * 
	 */
	protected function api_call()
	{
		if ( ! $result = parent::api_call('', false))
			throw new Kohana_User_Exception('Moo Driver', Kohana::lang('service.invalid_response', $this->last_api_call(), $this->last_status_code()));

		$xml = simplexml_load_string($result);

		if (false === $xml) 
			throw new Kohana_User_Exception('Moo Driver', Kohana::lang('service.xml_parse_error'));
		
		if (isset($xml->response->error))
			throw new Kohana_User_Exception('Moo Driver', Kohana::lang('service.response_error', (string) $xml->payload->error_string, $this->last_api_call()));

		return $xml;
	}

} // End Moo Driver